#!/usr/bin/env node

const { spawn } = require('child_process');
const path = require('path');

// 颜色输出
const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  magenta: '\x1b[35m',
  cyan: '\x1b[36m'
};

function colorLog(message, color = 'reset') {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

function printHeader() {
  colorLog('='.repeat(60), 'cyan');
  colorLog('           ASRClient 状态机单元测试套件', 'bright');
  colorLog('='.repeat(60), 'cyan');
  console.log();
}

function printUsage() {
  colorLog('使用方法:', 'yellow');
  console.log('  node run-tests.js [选项]');
  console.log();
  colorLog('选项:', 'yellow');
  console.log('  --all, -a          运行所有测试 (默认)');
  console.log('  --basic, -b        只运行基础功能测试');
  console.log('  --state, -s        只运行状态机深度测试');
  console.log('  --coverage, -c     运行测试并生成覆盖率报告');
  console.log('  --watch, -w        监视模式运行测试');
  console.log('  --verbose, -v      详细输出模式');
  console.log('  --help, -h         显示此帮助信息');
  console.log();
}

function runCommand(command, args, description) {
  return new Promise((resolve, reject) => {
    colorLog(`\n🚀 ${description}`, 'blue');
    colorLog(`执行命令: ${command} ${args.join(' ')}`, 'cyan');
    console.log();

    const child = spawn(command, args, {
      stdio: 'inherit',
      shell: true,
      cwd: __dirname
    });

    child.on('close', (code) => {
      if (code === 0) {
        colorLog(`\n✅ ${description} - 成功完成`, 'green');
        resolve(code);
      } else {
        colorLog(`\n❌ ${description} - 失败 (退出码: ${code})`, 'red');
        reject(new Error(`Command failed with exit code ${code}`));
      }
    });

    child.on('error', (error) => {
      colorLog(`\n❌ ${description} - 错误: ${error.message}`, 'red');
      reject(error);
    });
  });
}

async function checkDependencies() {
  try {
    colorLog('🔍 检查依赖...', 'yellow');
    await runCommand('npm', ['list', 'jest', 'ws'], '检查依赖');
  } catch (error) {
    colorLog('⚠️  依赖检查失败，尝试安装依赖...', 'yellow');
    try {
      await runCommand('npm', ['install'], '安装依赖');
    } catch (installError) {
      colorLog('❌ 依赖安装失败，请手动运行: npm install', 'red');
      process.exit(1);
    }
  }
}

async function main() {
  const args = process.argv.slice(2);
  
  printHeader();

  if (args.includes('--help') || args.includes('-h')) {
    printUsage();
    return;
  }

  try {
    await checkDependencies();

    if (args.includes('--coverage') || args.includes('-c')) {
      await runCommand('npm', ['run', 'test:coverage'], '运行测试并生成覆盖率报告');
    } else if (args.includes('--watch') || args.includes('-w')) {
      await runCommand('npm', ['run', 'test:watch'], '监视模式运行测试');
    } else if (args.includes('--verbose') || args.includes('-v')) {
      await runCommand('npm', ['run', 'test:verbose'], '详细输出模式运行测试');
    } else if (args.includes('--basic') || args.includes('-b')) {
      await runCommand('npx', ['jest', 'asrClient.test.js'], '运行基础功能测试');
    } else if (args.includes('--state') || args.includes('-s')) {
      await runCommand('npx', ['jest', 'stateMachine.test.js'], '运行状态机深度测试');
    } else {
      // 默认运行所有测试
      await runCommand('npm', ['test'], '运行所有测试');
    }

    colorLog('\n🎉 测试执行完成!', 'green');
    
    if (args.includes('--coverage') || args.includes('-c')) {
      colorLog('\n📊 覆盖率报告已生成:', 'cyan');
      colorLog('  - HTML报告: coverage/lcov-report/index.html', 'cyan');
      colorLog('  - LCOV报告: coverage/lcov.info', 'cyan');
    }

  } catch (error) {
    colorLog(`\n💥 测试执行失败: ${error.message}`, 'red');
    process.exit(1);
  }
}

// 处理未捕获的异常
process.on('uncaughtException', (error) => {
  colorLog(`\n💥 未捕获的异常: ${error.message}`, 'red');
  process.exit(1);
});

process.on('unhandledRejection', (reason, promise) => {
  colorLog(`\n💥 未处理的Promise拒绝: ${reason}`, 'red');
  process.exit(1);
});

// 处理Ctrl+C
process.on('SIGINT', () => {
  colorLog('\n\n👋 测试被用户中断', 'yellow');
  process.exit(0);
});

if (require.main === module) {
  main();
}